package com.ihome.android.market2.asynctask;

import java.net.URLEncoder;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.text.TextUtils;
import android.view.WindowManager;
import android.widget.Toast;

import com.ihome.android.EAApp;
import com.ihome.android.analytic.JsonAnalytic;
import com.ihome.android.common.ConfigUtil;
import com.ihome.android.dl.core.DownloadHelper;
import com.ihome.android.dl.core.DownloadTask;
import com.ihome.android.dl.util.DLFileInfo;
import com.ihome.android.dl.util.DownloadValues;
import com.ihome.android.http.HttpActions;
import com.ihome.android.http.HttpKeys;
import com.ihome.android.academy.R;
import com.ihome.android.market2.info.AppInfo;
import com.ihome.android.market2.view.DialogFactory;
import com.ihome.android.mod.LoginMod;
import com.ihome.android.util.AppMgr;
import com.ihome.android.util.AppUtils;
import com.ihome.android.util.BgInstallApk;
import com.ihome.android.util.Confirmation;
import com.ihome.android.util.exception.ITVException;
import com.ihome.android.util.log.LogUtil;

public class AppUpdateTask extends AsyncTask<Bundle, Integer, Bundle> {
	private String			TAG				= AppUpdateTask.class.getSimpleName();
	private Context			mContext;

	private AppInfo			mHandlerAppinfo;
	/** 下载监听广播接收器 */

	private DLFileInfo		currentFileInfo	= null;

	private HandlerThread	handlerThread	= new HandlerThread("AppUpdateTask_handler_thread");
	private Handler			mHandler;

	public AppUpdateTask(Context mContext) {
		this.mContext = mContext;

		handlerThread.start();
		mHandler = new Handler(handlerThread.getLooper()) {
			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				DownloadTask task = null;
				if (msg.obj instanceof DownloadTask) {
					task = (DownloadTask) msg.obj;
				}

				switch (msg.what) {
				case DownloadValues.Types.COMPLETE:
					handleCompletedAction(task.getAppInfo());
					break;
				case DownloadValues.Types.ERROR:
					handleError(task.getAppInfo(),task.getErrorCode(),task.getErrorInfo());
					break;
				default:
					break;
				}
			}
		};
		
		EAApp.getApp().addHandler(mHandler);

	}

	@Override
	protected Bundle doInBackground(Bundle... params) {
		Bundle b = params[0];
		String appPkgName = b.getString(HttpKeys.KEY_PACKAGENAME);
		try {
			if ((ConfigUtil.SessionKey == null && LoginMod.login(mContext)) || ConfigUtil.SessionKey != null) {
				appUpdate(appPkgName);
			}
		} catch (ITVException e) {
			b.putInt(HttpKeys.KEY_CODE, e.getStatusCode());
			b.putString(HttpKeys.KEY_DESCRIPTION, e.getMessage());
		}
		return b;
	}

	@Override
	protected void onPostExecute(Bundle result) {
		super.onPostExecute(result);

		int code = result.getInt(HttpKeys.KEY_CODE);
		String desc = result.getString(HttpKeys.KEY_DESCRIPTION);
		LogUtil.d(TAG, "AppName = " + mHandlerAppinfo.getAppName() + "; code = " + code + "; desc = " + desc);
		
		EAApp.getApp().clearHandler(mHandler);
		handlerThread.quit();

	}

	private void appUpdate(String appPkgName) throws ITVException {
		boolean isNeedUpdate = false;
		try {
			String param = "";
			JSONArray element = new JSONArray();
			JSONObject item = new JSONObject();
			item.put("pkgName", appPkgName);
			item.put("version", Confirmation.getVersion(mContext, appPkgName));
			LogUtil.v(TAG, "Check APP Need Update Item-->" + item.toString());
			element.put(item);
			param = URLEncoder.encode(element.toString(), "UTF-8");
			//TODO 根据包名检测是否需要升级
			String isupdateApp = new HttpActions(mContext).appIsUpdate(param);
			List<AppInfo> mListAppUTemp = JsonAnalytic.getInstance().anslyseUpdateAppResult(isupdateApp);
			for (int j = 0, len = mListAppUTemp.size(); j < len; j++) {
				LogUtil.v(TAG, "getNeedUpdateAppList() --> pkgName = " + mListAppUTemp.get(j).getPkgName() + " needUpdate = " + mListAppUTemp.get(j).isNeedUpdate());
				if (mListAppUTemp.get(j).isNeedUpdate()) {
					isNeedUpdate = true;
					mHandlerAppinfo = mListAppUTemp.get(j);
					break;
				}
			}
			if (isNeedUpdate) {
				String dlApp = new HttpActions(mContext).downApp(0, "" + mHandlerAppinfo.getAppId(), 0);
				LogUtil.v(TAG, "getAppUrl result-->" + dlApp);
				if (!TextUtils.isEmpty(dlApp)) {
					String appUrl = JsonAnalytic.getInstance().anslyseAppDLUrlResult(dlApp);
					String appMD5 = JsonAnalytic.getInstance().anslyseAppDLMD5Result(dlApp);
					startDLAPK(appUrl, mHandlerAppinfo.getAppName(), mHandlerAppinfo.getPkgName(), mHandlerAppinfo.getIconUrl(),appMD5);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * 文件下载成功
	 * 
	 * @param dLFileInfo
	 * @see [类、类#方法、类#成员]
	 */
	private void handleCompletedAction(DLFileInfo dLFileInfo) {
		LogUtil.d(TAG, "Download Completed ---> " + dLFileInfo.getFileName());

		if (currentFileInfo != null && currentFileInfo.getPkgName().equals(dLFileInfo.getPkgName())) {
			String apkPath = dLFileInfo.getFilePath() + dLFileInfo.getFileName();
			LogUtil.v(TAG, "apkPath = " + apkPath);
			Object[] chmodRusult = BgInstallApk.excuteShellComm("chmod 777 " + apkPath);
			LogUtil.d(TAG, "chmodRusult = " + ((Boolean)chmodRusult[0]).booleanValue());

			Object[] installResult= BgInstallApk.installAppInBackGround(apkPath, "-r");
			LogUtil.v(TAG, "installResult = " + installResult[0]);
			
			boolean installRst = ((Boolean)installResult[0]).booleanValue();

			if (installRst) {
				final AppInfo appInfo = AppMgr.getInstance().loadAppByPkgName(mContext, dLFileInfo.getPkgName());
				LogUtil.d(TAG, "PkgName = " + dLFileInfo.getPkgName());
				AlertDialog.Builder builder = new AlertDialog.Builder(mContext, R.style.AlterDialog);
				builder.setTitle(mContext.getString(R.string.app_name));
				builder.setMessage(mContext.getString(R.string.app_upgrade_success, appInfo.getAppName()));
				builder.setPositiveButton(mContext.getString(R.string.ok), new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						AppUtils.openApp(mContext, appInfo.getPkgName());
					}
				});
				builder.setNegativeButton(mContext.getString(R.string.cancel), new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {}
				});
				AlertDialog ad = builder.create();
				ad.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
				ad.setCanceledOnTouchOutside(true);
				ad.show();
			}
		}
	}

	/**
	 * 
	 * 解决下载过程中的错误
	 * 
	 * @param dLFileInfo
	 */
	public void handleError(DLFileInfo dLFileInfo,int errorCode, String errorInfo) {
		new DialogFactory(mContext).showDialog(EAApp.getApp().getString(R.string.attention_error), errorInfo);
	}
	
	/**
	 * 增加下载任务
	 */
	private void addDLFile(DLFileInfo dLFileInfo) {
		LogUtil.d(TAG, "Add DL File() --> = " + dLFileInfo.getFilePath() + dLFileInfo.getFileName());
		DownloadHelper.addNewTask(mContext, dLFileInfo, new DownloadHelper.PreDownloadStatusListener() {

			@Override
			public void sdCardCannotWriteOrRead(int errorCode, String errorInfo) {
				Toast.makeText(mContext, "不能读写SD卡", Toast.LENGTH_SHORT).show();
			}

			@Override
			public void notFoundSDCard(int errorCode, String errorInfo) {
				Toast.makeText(mContext, "没有SD卡", Toast.LENGTH_SHORT).show();
			}

			@Override
			public void moreTaskCount(int errorCode, String errorInfo) {
				Toast.makeText(mContext, "任务列表已满", Toast.LENGTH_SHORT).show();
			}
		});
	}

	/**
	 * 
	 * 开始下载APK
	 * 
	 * @param apkurl
	 * @see [类、类#方法、类#成员]
	 */
	public void startDLAPK(String apkurl, String appName, String pkgName, String iconUrl,String appMD5) {
		currentFileInfo = new DLFileInfo();
		currentFileInfo.setFilePath(ConfigUtil.FILE_PATH);
		currentFileInfo.setFileUrl(apkurl);
		currentFileInfo.setFileType("apk");
		currentFileInfo.setPkgName(pkgName);
		currentFileInfo.setFileName(appName + ".apk");
		currentFileInfo.setIconUrl(iconUrl);
		currentFileInfo.setMD5(appMD5);
		addDLFile(currentFileInfo);

		synchronized (currentFileInfo) {
			try {
				currentFileInfo.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

	}

}
